#ifndef MBEDTLS_SSM2_H
#define MBEDTLS_SSM2_H

#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#include "sm2.h"

#define MBEDTLS_ERR_SSM2_BAD_INPUT_DATA      -0x5800 /*!< Bad input parameters to function. */
#define MBEDTLS_ERR_SSM2_ALLOC_FAILED        -0x5880 /*!< Memory allocation failed. */
#define MBEDTLS_ERR_SSM2_KDF_FAILED          -0x5900 /*!< KDF got empty result. */
#define MBEDTLS_ERR_SSM2_DECRYPT_BAD_HASH    -0x5980 /*!< Bad C3 in SM2 decrypt */
#define MBEDTLS_ERR_SSM2_RANDOM_FAILED       -0x5A00 /*!< Generation of random value, such as (ephemeral) key, failed. */
#define MBEDTLS_ERR_SSM2_BAD_SIGNATURE       -0x5A80 /*!< Invalid signature */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief           Perform SPLITSM2 decryption
 *
 * \param ctxc      Client SM2 context
 * \param ctxs      Server SM2 context
 * \param md_alg    Algorithm that was used to hash the message
 * \param input     the ciphertext to be decrypt
 * \param ilen      the ciphertext length
 * \param output    buffer that will hold the plaintext
 * \param olen      will contain the plaintext length
 *
 * \return          0 if successful, or a error code
 */

int mbedtls_ssm2_decrypt(mbedtls_sm2_context *ctxc, mbedtls_sm2_context *ctxs,
                         mbedtls_md_type_t md_alg,
                         const unsigned char *input, size_t ilen,
                         unsigned char *output, size_t *olen);
/**
 * \brief           Compute SPLITSM2 signature of a previously hashed message
 *
 * \param ctx       SM2 context
 * \param md_alg    Algorithm that was used to hash the message
 * \param hash      Message digest
 * \param sig       Buffer holding the signature data
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
 *
 * \return          0 if successful, or a error code
 */

int mbedtls_ssm2_sign(mbedtls_sm2_context *ctxc, mbedtls_sm2_context *ctxs,
                      mbedtls_md_type_t md_alg,
                      const unsigned char *hash, unsigned char *sig,
                      int (*f_rng)(void *, unsigned char *, size_t), void *p_rng);
/**
 * \brief           Generate an SM2 keypair on the given curve
 *
 * \param ctx       SM2 context
 * \param gid       Group (elliptic curve) to use. One of the various
 *                  MBEDTLS_ECP_DP_XXX macros depending on configuration.
 * \param f_rng     RNG function
 * \param p_rng     RNG parameter
 *
 * \return          0 if successful, or a error code.
 */
int mbedtls_ssm2_genkey(mbedtls_sm2_context *ctxc,
                        mbedtls_sm2_context *ctxs,
                        mbedtls_ecp_group_id gid,
                        int (*f_rng)(void *, unsigned char *, size_t),
                        void *p_rng);

#ifdef __cplusplus
}
#endif


#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief           Checkup routine
 *
 * \return          0 if successful, or 1 if the test failed
 */
int mbedtls_ssm2_self_test(int verbose);

#ifdef __cplusplus
}
#endif

#endif /* sm2.h */
